﻿package {
	
import caurina.transitions.Tweener;
import pete.tools.Random;
import pete.tools.SplitChannels;
import flash.display.DisplayObject;
import flash.display.BlendMode;
import flash.errors.IllegalOperationError;
import flash.utils.Dictionary;



public class ColorError {
	
	// Properties
	// -----------------------------------------------------------
	
	public static var ease:String = "easeInBounce";
	
	private static var xx:Object = new Dictionary ();
	
	
	
	// Constructor
	// -----------------------------------------------------------
	
	public function ColorError(pvt:PrivateClass = null) {
		
		if (pvt == null) {
			throw new IllegalOperationError( "Instantiation failed: Use ColorError.getInstance() instead of new ColorError()." );
		}
	}
	
	private static var _instance:ColorError;
	
	public static function getInstance():ColorError {
		
		if (ColorError._instance == null) {
			
			ColorError._instance = new ColorError(new PrivateClass());
		}
		
		return ColorError._instance;
	}
	
	
	
	
	
	
	// Functions
	// -----------------------------------------------------------
	
	/**
	 * Starts a disaligning animation.
	 * @param target Object to animate.
	 * @param duration Duration of the animation (in seconds).
	 * @param peakFunction Function to call when the animation reaches its Peak.
	 */
	public function split(target:Object, duration:Number = 1, range:Number = 10, channels = "RGB"):void {
		
		if (xx[target] == undefined) {
			
			xx[target] 				= new Object();
			xx[target].animated 			= -1;
			xx[target].state 			= "join";
			xx[target].split 			= new SplitChannels(target);
			xx[target].split.mouseEnabled 	= false;
		}
		
		if (xx[target].animated == -1
		 && xx[target].state == "join") {
			
			xx[target].animated 			= 0;
			xx[target].state 			= "split";
			
			xx[target].split.x 			= target.x;
			xx[target].split.y 			= target.y;
			
			target.alpha 				= 0;
			target.parent.addChild		(xx[target].split);
			
			
			
			// Animate Red
			if (channels.indexOf("R") == -1) {
				
				xx[target].split.red.visible = false;
			}
			else {
				Tweener.addTween(xx[target].split.red, {
						   x		: Random.choose(-range, range), 
						   y		: Random.choose(-range, range),
						   scaleX	: Random.choose(9, 11) / 10,
						   scaleY	: Random.choose(9, 11) / 10,
						   time	: duration,
						   transition	: ease
				});
			}
			
			
			// Animate Green
			if (channels.indexOf("G") == -1) {
				
				xx[target].split.green.visible = false;
			}
			else {
				Tweener.addTween(xx[target].split.green, {
						   x		: Random.choose(-range, range), 
						   y		: Random.choose(-range, range),
						   scaleX	: Random.choose(9, 11) / 10,
						   scaleY	: Random.choose(9, 11) / 10,
						   time	: duration,
						   transition	: ease
				});
			}
			
			
			// Animate Blue
			if (channels.indexOf("B") == -1) {
				
				xx[target].split.blue.visible = false;
			}
			else {
				Tweener.addTween(xx[target].split.blue, {
						   x		: Random.choose(-range, range), 
						   y		: Random.choose(-range, range),
						   scaleX	: Random.choose(9, 11) / 10,
						   scaleY	: Random.choose(9, 11) / 10,
						   time	: duration,
						   transition	: ease
				});
			}
			
			
		}
	}
	
	public function join(target:Object, duration:Number, delay:Number = 0):void {
		
		if (xx[target].state == "split") {
			
			xx[target].animated = 0;
			xx[target].state =  "join";
			

			
			// Return
			Tweener.addTween(xx[target].split.red, {
					   x			: 0,
					   y			: 0,
					   scaleX		: 1,
					   scaleY		: 1,
					   time		: duration * .95,
					   delay		: delay,
					   transition		: ease
			});
			
			
			Tweener.addTween(xx[target].split.green, {
					   x			: 0,
					   y			: 0,
					   scaleX		: 1,
					   scaleY		: 1,
					   time		: duration * .95,
					   delay		: delay,
					   transition		: ease
			});
			
			
			Tweener.addTween(xx[target].split.red, {
					   x			: 0,
					   y			: 0,
					   scaleX		: 1,
					   scaleY		: 1,
					   time		: duration,
					   delay		: delay,
					   transition		: ease,
					   onComplete		: stop,
					   onCompleteParams	: [target]
			});
		}
		
	}
	
	
	public function stop(target:Object):void {
		
		target.parent.removeChild	(xx[target].split);
		target.alpha 			= 1;
		
		xx[target].animated 		= -1;
	}
}
	
}


class PrivateClass { public function PrivateClass() {} }
